package mysqlgorm

import (
	"os"
	"path/filepath"
	"strings"
	"sync"

	Log "github.com/cihub/seelog"
	"gopkg.in/ini.v1"
	"gorm.io/driver/mysql"
	gg "gorm.io/gorm"
	"gorm.io/gorm/logger"
)

type GormDB = *gg.DB

var (
	gormOnce    sync.Once
	globGormDB  *gg.DB            //数据库操作对象
	dbVariables map[string]string //数据库名称映射集合
)

// 初始化
func init() {
	InitDB()
}

// 初始化数据库加载配置
func InitDB() {
	gormOnce.Do(func() {
		root := ""
		exePath, err := os.Executable()
		if err != nil {
			root = "."
		}

		root, _ = filepath.EvalSymlinks(filepath.Dir(exePath))

		configFilePath := strings.Replace(root+"/config/app.ini", "\\", "/", -1)

		_, err = os.Stat(configFilePath) //os.Stat获取文件信息
		if err != nil {
			if !os.IsExist(err) {
				Log.Error("配置文件不存在:", err)
				os.Exit(1)
				return
			}
		}

		cfg, err := ini.Load(configFilePath)
		if err != nil {
			Log.Error("配置文件读取错误:", err)
			os.Exit(1)
		}

		if !cfg.HasSection("DataSource") {
			Log.Debug("配置文件没有DataSource,不进行数据库连接")
			return
		}

		dbVariables = make(map[string]string)

		DbVariables := cfg.Section("DbVariables")
		for i := 0; i < len(DbVariables.Keys()); i++ {
			key := DbVariables.Keys()[i].Name()
			value, _ := DbVariables.GetKey(key)
			if value != nil {
				dbVariables[key] = value.String()
			}
		}

		DataSource := cfg.Section("DataSource")

		user := "root"
		value, _ := DataSource.GetKey("User")
		if value != nil {
			user = value.String()
		}

		pass := "view"
		value, _ = DataSource.GetKey("Pass")
		if value != nil {
			pass = value.String()
		}

		if (strings.HasPrefix(pass, "${")) && (strings.HasSuffix(pass, "}")) {
			pass = AesUtil{}.Decrypt(pass[2:len(pass)-1], "bricks")
		}

		ip := "127.0.0.1"
		value, _ = DataSource.GetKey("Ip")
		if value != nil {
			ip = value.String()
		}

		port := "3306"
		value, _ = DataSource.GetKey("Port")
		if value != nil {
			port = value.String()
		}

		dbName := "mysql" //如果是sqlite则是数据库文件路径和名称
		value, _ = DataSource.GetKey("MainDb")
		if value != nil {
			dbName = value.String()
		}

		PrintSql := false
		value, _ = DataSource.GetKey("PrintSql")
		if value != nil {
			tmp, _ := value.Int()
			PrintSql = tmp == 1
		}

		AutoMigrate := false //是否开启AutoMigrate功能(会创建表、缺失的外键、约束、列和索引)
		value, _ = DataSource.GetKey("AutoMigrate")
		if value != nil {
			tmp, _ := value.Int()
			AutoMigrate = tmp == 1
		}

		dbConfig := &gg.Config{
			DisableForeignKeyConstraintWhenMigrating: !AutoMigrate,
		}

		if PrintSql {
			dbConfig.Logger = logger.Default.LogMode(logger.Info) //开启sql打印
		}

		//dsn := "root:view@tcp(127.0.0.1:3306)/Dev_BricksBaseSystem?charset=utf8mb4&parseTime=True&loc=Local"
		//dsn := user + ":" + pass + "@tcp(" + ip + ":" + port + ")/" + dbName + "?charset=utf8mb4&serverTimezone=GMT%2B8&parseTime=True&loc=Local"
		dsn := user + ":" + pass + "@tcp(" + ip + ":" + port + ")/" + dbName + "?charset=utf8mb4&parseTime=True&loc=Local"
		//dsn := user + ":" + pass + "@tcp(" + ip + ":" + port + ")/" + dbName + "?charset=utf8mb4&loc=Local"
		globGormDB, err = gg.Open(mysql.Open(dsn), dbConfig)

		if err != nil {
			Log.Error("连接数据库错误:", err)
			return
		}
	})
}

// 取gorm操作对象
func GetDB() GormDB {
	return globGormDB
}
